﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text.RegularExpressions;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Vit.Common.Extensions;
using VitData = Vit.Web.DataAnnotations;

namespace Vit.CMS.Data
{
    [MetadataType(typeof(ContentReplaceInfoMetaData))]
    public class ContentReplaceInfo : Vit.Common.IStringSerializable
    {
        public ContentReplaceInfo(PageInfo pageInfo, object parent)
        {
            ControlsInfo = new List<object>();

            PageInfo = pageInfo;
            Parent = parent;
        }

        public List<object> ControlsInfo { get; set; }

        public string ReplaceControlID { get; set; }
        public string Content { get; set; }
        public string ID { get; set; }
        public int Indent { get; set; }

        public PageInfo PageInfo { get; private set; }
        public object Parent { get; private set; }

        #region IStringSerializable Members

        public string Serialize()
        {
            string content = "";
            foreach (object con in ControlsInfo)
            {
                if (con is ControlLoaderInfo)
                {
                    ((ControlLoaderInfo)con).Indent = Indent + 1;
                    content += ((ControlLoaderInfo)con).Serialize();
                }
                else if (con is MvcControlInfo)
                {
                    ((MvcControlInfo)con).Indent = Indent + 1;
                    content += ((MvcControlInfo)con).Serialize();
                }

                content += "\r\n";
            }

            string html = string.Format(@"{0}<vit:ContentReplace ID=""{1}"" runat=""server"" ReplaceControlID=""{2}"">
{3}
{0}</vit:ContentReplace>", "\t".Repeat(Indent), ID, ReplaceControlID, content.TrimEnd());

            return html;
        }

        public void Deserialize(string value)
        {
            string ns = "vit:ContentReplace";
            string pattern = string.Format(@"<{0}\s*(?<attributes>[^<>]*?)\s*((/>)|(>(?<content>(.|\r|\n)*?)</{0}>))", ns);
            Match match = null;
            RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Multiline;

            string attibutes = "";
            match = Regex.Match(value, pattern, options);
            if (match.Success)
            {
                attibutes = match.Groups["attributes"].Value.Trim();
                this.Content = match.Groups["content"].Value.Trim();
            }

            pattern = @"ID\s*=\s*""(?<content>[^<>]+?)""";
            match = Regex.Match(attibutes, pattern, options);
            if (match.Success)
                this.ID = match.Groups["content"].Value.Trim();

            pattern = @"ReplaceControlID\s*=\s*""(?<content>[^<>]+?)""";
            match = Regex.Match(attibutes, pattern, options);
            if (match.Success)
                this.ReplaceControlID = match.Groups["content"].Value.Trim();

            if (!string.IsNullOrEmpty(this.Content))
            {
                pattern = @"<vit:(?<type>(ControlLoader|MvcControl))[^<>]*?((/>)|(>(.|\r|\n)*?</vit:\1>))";
                MatchCollection ms = Regex.Matches(this.Content, pattern, options);
                foreach (Match m in ms)
                {
                    string type = m.Groups["type"].Value.Trim().ToLower();
                    switch (type)
                    {
                        case "controlloader":
                            ControlLoaderInfo loader = new ControlLoaderInfo(PageInfo, this);
                            loader.Deserialize(m.Value);
                            this.ControlsInfo.Add(loader);
                            break;
                        case "mvccontrol":
                            MvcControlInfo mvc = new MvcControlInfo(PageInfo, this);
                            mvc.Deserialize(m.Value);
                            this.ControlsInfo.Add(mvc);
                            break;
                    }
                }
            }
        }

        #endregion

        public class ContentReplaceInfoMetaData
        {
            [VitData.DisplayName("ContentReplaceInfo.ControlsInfo")]
            [UIHint("ControlsInfo")]
            public List<object> ControlsInfo { get; set; }

            [VitData.DisplayName("ContentReplaceInfo.ID")]
            public string ID { get; set; }
            [VitData.DisplayName("ContentReplaceInfo.ReplaceControlID")]
            public string ReplaceControlID { get; set; }
            [ScaffoldColumn(false)]
            public string Content { get; set; }
            [ScaffoldColumn(false)]
            public int Indent { get; set; }

            [ScaffoldColumn(false)]
            public PageInfo PageInfo { get; private set; }
            [ScaffoldColumn(false)]
            public object Parent { get; private set; }
        }
    }
}
